package com.opener.web.service.sys.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.opener.web.dao.sys.SysDictDao;
import com.opener.web.model.sys.SysConf;
import com.opener.web.model.sys.SysDict;
import com.opener.web.model.sys.SysDictSearchArgs;
import com.opener.web.service.cache.CacheService;
import com.opener.web.service.sys.SysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by baboy on 07/12/2016.
 */
@Service
public class SysDictServiceImpl implements SysDictService {
    public static class ValueType{
        public static String STRING = "String";
        public static String INT = "Integer";
        public static String Long = "Long";
        public static String LIST = "List";
        public static String MAP = "HashMap";
    }
    @Autowired
    protected SysDictDao sysDictDao;

    @Autowired
    @Qualifier("memoryCacheService")
    private CacheService cacheService;
    private static final String CACHE_KEY = "sys_dict_cache_key";
    private Integer cacheExpireTimeInSeconds = 60;
    private static HashMap<String, SysDict.SysDictItem> itemCachePool = new HashMap<String, SysDict.SysDictItem>();
    private static HashMap<String, SysDict> dictCachePool = new HashMap<String, SysDict>();

    public Integer getCacheExpireTimeInSeconds() {
        return cacheExpireTimeInSeconds;
    }

    @Override
    public void setCacheExpireTimeInSeconds(Integer cacheExpireTimeInSeconds) {
        this.cacheExpireTimeInSeconds = cacheExpireTimeInSeconds;
    }

    @Override
    public Integer add(SysDict dict) {
        Integer ret = sysDictDao.add(dict);
        clearCache();
        return ret > 0 ? dict.getId() : null;
    }

    @Override
    public boolean update(SysDict dict) {
        sysDictDao.update(dict);
        if (dict.getItems() != null) {
            sysDictDao.removeItems(dict.getId());
            for (SysDict.SysDictItem item : dict.getItems()) {
                item.setDictId(dict.getId());
            }
            sysDictDao.addItems(dict.getItems());
        }
        clearCache();
        return true;
    }

    @Override
    public boolean addItems(String dictKey, List<SysDict.SysDictItem> items) {
        SysDict dict = getByKey(dictKey);
        for (SysDict.SysDictItem item : items){
            item.setDictId(dict.getId());
        }
        boolean ret = sysDictDao.addItems(items);
        clearCache();
        return ret;
    }

    @Override
    public boolean removeItems(String dictKey) {
        SysDict dict = getByKey(dictKey);
        boolean ret = sysDictDao.removeItems(dict.getId());
        clearCache();
        return ret;
    }

    @Override
    public List<SysDict> search(SysDictSearchArgs searchArgs) {
        return sysDictDao.search( searchArgs);
    }


    @Override
    public SysDict getByKey(String key) {
        refreshCache();
        return dictCachePool.get(key);
    }

    @Override
    public SysDict.SysDictItem getItem(String dictKey, String itemKey) {
        refreshCache();
        return itemCachePool.get(dictKey+"."+itemKey);
    }

    @Override
    public String getItemValue(String dictKey, String itemKey){
        SysDict.SysDictItem item = getItem(dictKey, itemKey);
        if (item != null){
            return item.getValue();
        }
        return null;
    }
    @Override
    public Object getItemTypedValue(String dictKey, String itemKey){
        SysDict.SysDictItem item = getItem(dictKey, itemKey);
        if (item != null){
            return item.getTypedValue();
        }
        return null;
    }
    private void clearCache(){
        cacheService.remove(CACHE_KEY);
    }
    private void refreshCache(){
        this.getAllDicts();
    }
    @Override
    synchronized public List<SysDict> getAllDicts(){
        List<SysDict> ret = (List<SysDict>)cacheService.get( CACHE_KEY );
        if (ret == null){
            //缓存
           ret = this.search(new SysDictSearchArgs());
           cacheService.set(CACHE_KEY, ret, cacheExpireTimeInSeconds);
           if(ret != null){
               for (SysDict d: ret){
                   String k1 = d.getKey();
                   dictCachePool.put(k1, d);
                   for (SysDict.SysDictItem item : d.getItems()){
                       String k2 = item.getKey();
                       itemCachePool.put(k1+"."+k2, item);
                   }
               }
           }
        }
        return ret;
    }
}
